iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
JavaScript

從看不懂到做出來,用 PawPal 走過前端新手村系列 第 23

Day 23|部署前的最後一哩路:環境變數與設定檔。

  • 分享至 

  • xImage
  •  

今天的故事

在 PawPal 開發到後期時,前端部署到 Vercel 這一塊主要是由我負責。

一開始我對「部署」這件事的想像其實很簡單。

網站在自己的電腦可以正常開、功能可以跑,接下來應該就是:

把專案放到 Vercel
↓
Build
↓
網址打開
↓
完成

但真的開始處理部署之後,我才發現:

本機可以正常執行,跟正式環境可以正常執行,其實是兩件不同的事。

有些問題,在自己的電腦上甚至完全看不出來。

一定要真的把網站放到正式環境,才會知道還有哪些地方沒有處理好。


本機明明正常,部署後卻出現 404

其中一個讓我很有印象的問題,是 PawPal 部署到 Vercel 之後遇到的頁面 404。

我們在本機開發時,從首頁切到 Dashboard、行事曆或其他頁面都很正常。

但部署之後卻發現:

如果直接進入某些網址,或是在那個頁面按重新整理,就可能直接看到:

404 Not Found

我當時很疑惑。

因為 Vue Router 明明有這個頁面。

為什麼從網站裡面點進去可以,重新整理之後卻不行?

後來團隊一起排查,我才慢慢理解:

Vue Router 知道 /dashboard 是哪個頁面,不代表部署平台一開始也知道。


原來重新整理之後,是 Vercel 先收到網址

PawPal 使用 Vue Router 的 history mode。

網站已經載入之後,可以先用「簡化概念」理解:

使用者切換頁面
↓
Vue Router 判斷網址
↓
顯示對應畫面

但如果直接開:

/dashboard

或是在這個頁面重新整理,瀏覽器會先把這個網址交給部署平台。

如果部署平台不知道這個路徑應該交給 Vue App 處理,就可能直接回傳 404。

後來團隊透過 Vercel 的 rewrite 設定來處理這個問題:

{
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/index.html"
    }
  ]
}

可以用「簡化概念」理解成:

使用者直接進入某個網址
↓
Vercel 先回傳 index.html
↓
Vue App 啟動
↓
Vue Router 再判斷要顯示哪個頁面

這個問題不是我一個人解決的,而是團隊一起遇到、一起排查。

但也是從這次開始,我第一次很明顯感受到:

本機開發環境其實默默幫我們處理了很多事情,到了正式環境,就要重新確認這些設定。


另一個讓我弄很久才懂的東西:環境變數

除了 Router,部署過程中另一個讓我卡很久的,就是環境變數。

PawPal 開發到後面,不同功能陸續需要不同的環境設定。

前端像是會使用:

VITE_API_BASE_URL

VITE_GOOGLE_CLIENT_ID

VITE_LINE_CHANNEL_ID

當組員做的新功能需要新增或修改環境變數時,通常也會再來找我,到 Vercel 裡調整正式環境的設定。

但老實說,一開始的我比較像是:

組員:

這個功能要加一個環境變數

我:

好,我去 Vercel 設

我知道自己「要做什麼」。

可是那時候還沒有真的理解:

為什麼本機 .env 已經有了,Vercel 還要再設定一次?

現在回頭看,我覺得當時的自己其實是:

會設定,但還沒有真的懂環境變數。

我照著需求設定了好幾次之後,才慢慢搞懂:

不是「.env 有寫就好」,而是每個執行環境都有自己的設定。


我的電腦有 .env,不代表 Vercel 也有

以前我會很自然地把 .env 想成:

專案的環境變數設定檔。

後來才發現,還要多問一件事:

這是哪一個環境的設定?

本機開發時,可以用「簡化概念」理解成:

Source Code
↓
本機 .env
↓
Vite Dev Server
↓
網站

部署時則會變成:

Source Code
↓
Vercel Environment Variables
↓
vite build
↓
正式網站

也就是說:

我的電腦
≠
Vercel

我電腦裡有的 .env,Vercel 並不會因此自動知道裡面的設定。

所以很容易出現:

本機有設定
↓
功能正常

但正式環境少了同一個設定後:

Vercel 沒有對應設定
↓
部署後功能出問題

這時候問題甚至不一定是程式寫錯。

可能只是正式環境少了它需要的設定。


我也是到這時候才把 build 和環境變數連起來

以前開發時,我最常使用:

npm run dev

所以很容易把眼前看到的網站當成:

最後部署出去大概也是這樣。

但正式部署前,PawPal 還會經過:

npm run build

背後執行的是:

vite build

部署時,前端 build 會用到的環境變數也必須存在於 Vercel 的部署環境中,Vite 才能用正確的設定產生正式版本。

可以用「簡化概念」理解:

Source Code
+
部署環境設定
↓
vite build
↓
產生部署用檔案
↓
Vercel

也是到了這個階段,我才把原本分開理解的:

.env

build

部署

三件事情慢慢連在一起。


放在 .env 裡,不代表它就是秘密

環境變數還有一個我後來才注意到的地方。

PawPal 前端使用 Vite,會讀取像:

VITE_API_BASE_URL

這類 VITE_* 變數。

在 Vite 裡,VITE_* 變數會暴露給前端程式碼使用,並進入前端建置結果。

所以不能因為它寫在 .env 裡,就覺得:

這個值一定是安全的。

像 API Base URL、Client ID 這類本來就要提供給前端使用的資訊,可以作為前端環境設定。

但真正需要保密的東西,例如:

資料庫密碼

JWT Secret

Server-side Secret

就不能放進前端可以讀取的 VITE_* 變數。

這時候我才比較理解:

.env 是用來管理不同環境的設定,不是把資料藏起來的魔法。


如果現在重新部署,我會先確認三件事

如果現在重新做一次類似的專案,我不會再因為本機所有功能都可以跑,就直接覺得:

應該可以上線了。

第一個我會確認的是 Router。

如果使用 SPA 和 history mode,我會先想到:

使用者直接進入某個 route,或重新整理時,正式環境能不能正確處理?

第二個是本機和正式環境的差異。

我會開始去確認:

本機正常
≠
正式環境一定正常

像是 build、部署平台和相關設定。

第三個則是環境變數。

如果後來增加一個新的 env,我會同時確認:

本機需要更新嗎?
↓
Vercel 需要更新嗎?

而不是只修改其中一邊。

但我也不會覺得專案一開始就能把所有環境變數全部列出來。

因為很多設定,本來就是功能做到後面才陸續出現。

真正重要的是:

每次新的環境需求出現時,知道自己還需要確認哪些地方。


部署讓我開始注意「環境」

以前寫功能時,我最常注意的是:

畫面有沒有正常?

API 有沒有回資料?

功能有沒有跑?

開始負責部署之後,我看程式的方式也變了。

以前只會問:

功能有沒有跑?

現在還會多問一句:

它現在是在哪個環境跑?

因為到了另一個環境,Router、環境變數、build 和部署平台,都可能帶來新的問題。

部署不是把網站從 localhost 搬到網路上,而是讓同一份程式開始面對另一個環境。


下一篇預告

Router、環境變數、build 和部署設定慢慢處理完之後,PawPal 終於越來越接近真正上線。

下一步,就是讓網站真的有一個大家都能打開的正式網址。

而當我第一次看到 PawPal 真正在線上跑起來時,那個感覺和看著 localhost 完全不一樣。

下一篇:

Day 24|部署成功的那一刻,我差點哭出來。


上一篇
Day 22|合併衝突!我第一次和 Git 打起來。
下一篇
Day 24|部署成功的那一刻,我差點哭出來。
系列文
從看不懂到做出來,用 PawPal 走過前端新手村24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言